Add BoringSSL support to the ja4_fingerprint plugin#12914
Add BoringSSL support to the ja4_fingerprint plugin#12914maskit merged 25 commits intoapache:masterfrom
Conversation
2f7802f to
eaf9582
Compare
eaf9582 to
293f873
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds BoringSSL support to the ja4_fingerprint plugin by introducing a new TSClientHello API that abstracts TLS ClientHello access across both OpenSSL and BoringSSL implementations. The changes build upon PR #12790 with optimizations to eliminate heap allocations by returning objects by value and using a custom iterator class instead of std::vector for extension types.
Changes:
- Introduces
TSVConnClientHelloGet()andTSClientHelloExtensionGet()plugin APIs that work with both BoringSSL and OpenSSL - Implements a custom
TSExtensionTypeListiterator class to avoid heap allocations when accessing extension type IDs - Updates ja4_fingerprint plugin to use the new API, enabling BoringSSL compatibility
- Removes the OpenSSL-only build dependency from the ja4_fingerprint plugin
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
src/iocore/net/TLSSNISupport.cc |
Implements ClientHello getters and custom iterator for extension IDs with OpenSSL/BoringSSL conditional compilation |
src/iocore/net/TLSSNISupport.h |
Defines ClientHello class with ExtensionIdIterator and adds _ch member to store ClientHello reference |
src/api/InkAPI.cc |
Implements TSClientHello wrapper class methods and TSVConnClientHelloGet/TSClientHelloExtensionGet APIs |
include/ts/ts.h |
Declares new public API functions with comprehensive documentation |
include/ts/apidefs.h.in |
Defines TSClientHello class with custom iterator wrapping internal implementation |
plugins/experimental/ja4_fingerprint/plugin.cc |
Updates to use TSClientHello API instead of direct OpenSSL calls, enabling BoringSSL support |
plugins/experimental/ja4_fingerprint/README.md |
Documents BoringSSL support |
doc/developer-guide/api/types/TSClientHello.en.rst |
Developer documentation for TSClientHello type |
doc/developer-guide/api/functions/TSVConnClientHelloGet.en.rst |
Developer documentation for API functions |
doc/admin-guide/plugins/ja4_fingerprint.en.rst |
Administrator guide for ja4_fingerprint plugin |
doc/admin-guide/plugins/index.en.rst |
Adds ja4_fingerprint to plugin index |
cmake/ExperimentalPlugins.cmake |
Removes OpenSSL-specific dependency check for JA4_FINGERPRINT |
|
[approve ci autest 1] |
bneradt
left a comment
There was a problem hiding this comment.
Looks reasonable. We've been through a lot of discussion on this between the three of us.
I just have a few nit-picky @param doxygen comment requests.
include/ts/ts.h
Outdated
| specific callback functions. Calling this function outside of the client | ||
| hello hook may result in unavailable object being returned. | ||
|
|
||
| @param sslp The SSL virtual connection handle. Must not be nullptr. |
include/ts/ts.h
Outdated
| @param ch The Client Hello object obtained from TSVConnClientHelloGet(). | ||
| @param type The TLS extension type to retrieve. | ||
| @param out Pointer to receive the extension data buffer. Must not be nullptr. | ||
| @param outlen Pointer to receive the length of the extension data in bytes. |
There was a problem hiding this comment.
[in], [in], [out], [out] please.
This PR is based on #12790, and most work was done by @jasmine-nahrain. Please look at the PR for the overall description. I made additional changes to eliminate the heap allocations that were introduced on the PR.
Additional changes:
TSVConnClientHelloGetreturns a object by value instead of a pointerTSClientHelloDestroysince the returned value is no longer a pointerTSExtensionTypeListto a custom class that supports range-based for-loop (this eliminates the use ofstd::vector).Changes for the plugin code are trivial:
TSClientHellobyis_available()instead of comparing withnullptr->to.sinceTSClientHellois no longer a pointerTSClientHelloDestroyNow all getters access the original data in a library specific data structure. Plugin developers can copy things by themselves if they need to. At a minimum, it's not necessary for this (ja4) plugin.
The internal implementation is getting a little messy. I think
TLSSNISupport::ClientHelloshould be decoupled fromTLSSNISupport, but the change wouldn't affect the plugin API, so we can do it later.